#include "vtor_reg.h"

#ifdef __VTOR_REG__


// 自身地址
uint8_t VtorReg_selfId = 0x01;
uint8_t* VtorReg_selfRegBuf = NULL;
uint16_t VtorReg_selfRegCnt = 0;
uint8_t VtorReg_txFrameBuf[128] = {0};

// 计算数据的CRC8校验
uint8_t VtorReg_CalcCrc(const uint8_t* dataBuf, int16_t dataLen)
{
	uint8_t crc = 0;
	for (int16_t i = 0; i < dataLen; i++)
	{
		crc ^= dataBuf[i];
		for (uint8_t j = 0; j < 8; j++)
		{
			if (crc & 0x80)
			{
				crc = (crc << 1) ^ 0x07;
			}
			else
			{
				crc <<= 1;
			}
		}
	}
	return crc;
}

void VtorReg_WriteSelfReg(uint16_t regAddr, uint16_t regNum, uint8_t* regBuf)
{
	memcpy(VtorReg_selfRegBuf + regAddr, regBuf, regNum);
}

void VtorReg_ReadSelfReg(uint16_t regAddr, uint16_t regNum, uint8_t* regBuf)
{
	memcpy(regBuf, VtorReg_selfRegBuf + regAddr, regNum);
}

// 写入其他设备寄存器
void VtorReg_WriteReg(uint8_t rxId, uint16_t regAddr, uint16_t regNum)
{
	if (VtorReg_selfId == rxId || regNum == 0)
		return;
	// 构建请求帧
	uint16_t frameLen = VtorReg_BaseLen + regNum; // 基本字段 + 数据
	VtorRegFrame* txFrame = (VtorRegFrame*)VtorReg_txFrameBuf;

	txFrame->frameHead = FRAME_HEADER;
	txFrame->txId = VtorReg_selfId;
	txFrame->rxId = rxId;
	txFrame->cmd = VtorReg_RequestWrite;
	txFrame->regAddr1 = regAddr >> 8;
	txFrame->regAddr0 = regAddr & 0xff;
	txFrame->regNum1 = regNum >> 8;
	txFrame->regNum0 = regNum & 0xff;
	// 把自身的寄存器数据写给别的机器
	VtorReg_ReadSelfReg(regAddr, regNum, txFrame->regBuf);

	// 计算帧CRC
	uint8_t frameCrc = VtorReg_CalcCrc(VtorReg_txFrameBuf, frameLen - 1);
	VtorReg_txFrameBuf[frameLen - 1] = frameCrc;

	VtorReg_Transmit(VtorReg_txFrameBuf, frameLen);
}


// 读取其他设备寄存器
void VtorReg_ReadReg(uint8_t rxId, uint16_t regAddr, uint16_t regNum)
{
	if (VtorReg_selfId == rxId)
	{
		return ;
	}
	// 构建请求帧
	uint16_t frameLen = VtorReg_BaseLen; // 基本字段
	VtorRegFrame* txFrame = (VtorRegFrame*)VtorReg_txFrameBuf;

	txFrame->frameHead = FRAME_HEADER;
	txFrame->txId = VtorReg_selfId;
	txFrame->rxId = rxId;
	txFrame->cmd = VtorReg_RequestRead;
	txFrame->regAddr1 = regAddr >> 8;
	txFrame->regAddr0 = regAddr & 0xff;
	txFrame->regNum1 = regNum >> 8;
	txFrame->regNum0 = regNum & 0xff;

	// 计算帧CRC（不包括帧头）
	uint8_t frameCrc = VtorReg_CalcCrc(VtorReg_txFrameBuf, frameLen - 1);
	VtorReg_txFrameBuf[frameLen - 1] = frameCrc;
	
	VtorReg_Transmit(VtorReg_txFrameBuf, frameLen);
}

// 处理接收到的帧
void VtorReg_Process(const uint8_t* rxFrameBuf, int16_t rxFrameLen)
{
	VtorRegFrame* rxFrame = (VtorRegFrame*)rxFrameBuf;
	uint16_t regAddr = 0;
	uint16_t regNum = 0;
	if (rxFrame == NULL || rxFrameLen < 8)
	{
		return; // 无效帧
	}
	
	if (rxFrame->frameHead != FRAME_HEADER
		|| rxFrame->rxId != VtorReg_selfId)
	{
		return;
	}
#ifdef __VtorReg_ConfigIgnoreCrc__
#else
	// 检查帧CRC
	uint8_t rxFrameCrc = rxFrameBuf[rxFrameLen - 1];
	uint8_t rxFrameCalcCrc = VtorReg_CalcCrc(rxFrameBuf, rxFrameLen - 1);

	if (rxFrameCrc != rxFrameCalcCrc)
	{
		return;
	}
#endif

	
	VtorRegFrame* txFrame = (VtorRegFrame*)VtorReg_txFrameBuf;
	uint16_t txFrameLen = VtorReg_BaseLen; // 基本字段

	txFrame->frameHead = FRAME_HEADER;
	txFrame->txId = VtorReg_selfId;
	txFrame->rxId = rxFrame->txId;
	//txFrame->cmd = xxxxxxxxxxxxxxxx; // 命令暂不确定
	txFrame->regAddr1 = rxFrame->regAddr1;
	txFrame->regAddr0 = rxFrame->regAddr0;
	txFrame->regNum1 = rxFrame->regNum1;
	txFrame->regNum0 = rxFrame->regNum0;

	txFrame->regBuf[0] = 0;
	
	regAddr = txFrame->regAddr1 << 8 | txFrame->regAddr0;
	regNum = txFrame->regNum1 << 8 |txFrame->regNum0;
	switch (rxFrame->cmd)
	{
	case VtorReg_RequestRead: // 处理读请求
		txFrame->cmd = VtorReg_ResponseRead;
	
		// 获取自身寄存器数据，更新返回帧长度
	
		VtorReg_ReadSelfReg(regAddr, regNum, txFrame->regBuf);
		txFrameLen += regNum;
		
		// 计算CRC并发送
		VtorReg_txFrameBuf[txFrameLen - 1]
			= VtorReg_CalcCrc(VtorReg_txFrameBuf, txFrameLen - 1);
		VtorReg_Transmit(VtorReg_txFrameBuf, txFrameLen);
	break;

	case VtorReg_RequestWrite: // 处理写请求
		txFrame->cmd = VtorReg_ResponseWrite;
		
		// 写自身寄存器数据
		VtorReg_WriteSelfReg(regAddr, regNum, rxFrame->regBuf);

		// 计算帧CRC并发送
		VtorReg_txFrameBuf[txFrameLen - 1]
			= VtorReg_CalcCrc(VtorReg_txFrameBuf, txFrameLen - 1);
		VtorReg_Transmit(VtorReg_txFrameBuf, txFrameLen);
		
	break;

	case VtorReg_ResponseRead:
		
	case VtorReg_ResponseWrite:
		// 处理响应（这里简化处理，实际应该通知等待的调用者）
	break;

	default:
	break;
	}
}

void VtorReg_WriteRegTest()
{
	uint8_t i = 0;
	static uint8_t VtorReg_testWriteBuf[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	for(i = 0; i < 10; i++)
	{
		VtorReg_testWriteBuf[i]++;
	}
	// 修改自身，再同步给其他设备
	VtorReg_WriteSelfReg(0, 1, VtorReg_testWriteBuf);
	VtorReg_WriteReg(2, 0, 1);
}

void VtorReg_ReadRegTest()
{
	static uint8_t VtorReg_testReadBuf[10] = {0};
	// 修改自身，再从其他设备读回数据
	VtorReg_WriteSelfReg(0, 1, VtorReg_testReadBuf);
	VtorReg_ReadReg(2, 0, 1);
	
}


#endif // __VTOR_REG__

